#include<iostream>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<opencv2/opencv.hpp>
#include<opencv2/features2d/features2d.hpp>
#include<opencv2/highgui/highgui.hpp>
#include "Utility.h"
#include "brisk/brisk.h"
#define TEST 15
#define OVERLAP 21

void testRepeatability(int clientsNumber,float overlap)
{
	cout<<"Setting up BRISK..."<<endl;
	int threshold = 40;
	int octave = 4;
	int cols,slice,ovl;
	char image[50];
	Ptr<FeatureDetector> detector = new cv::BriskFeatureDetector(threshold,octave);
	Ptr<DescriptorExtractor> descriptorExtractor = new cv::BriskDescriptorExtractor();
	FILE* offloading = fopen("/home/ubuntu/offloadingTest.txt","a+");
	if(offloading == NULL)
		return;
	for(int h = 10; h < TEST; h++)
	{
		int i,row;
		vector<KeyPoint> vectorOriginal, vectorDistributed,vectorOffloading;
		Mat descriptor,descriptorDistributed;
		Mat original;
		Mat splitImage[clientsNumber+1];
		if(h==0)
			original = imread("/home/ubuntu/testImage/1.png",0);
		if(h==1)
			original = imread("/home/ubuntu/testImage/2.png",0);
		if(h==2)
			original = imread("/home/ubuntu/testImage/3.png",0);
		if(h==3)
			original = imread("/home/ubuntu/testImage/4.png",0);
		if(h==4)
			original = imread("/home/ubuntu/testImage/5.png",0);
		if(h==5)
			original = imread("/home/ubuntu/testImage/6.png",0);
		if(h==6)
			original = imread("/home/ubuntu/testImage/7.png",0);
		if(h==7)
			original = imread("/home/ubuntu/testImage/8.png",0);
		if(h==8)
			original = imread("/home/ubuntu/testImage/9.png",0);
		if(h==9)
			original = imread("/home/ubuntu/testImage/10.png",0);
		if(h==10)
			original = imread("/home/ubuntu/testImage/11.png",0);
		if(h==11)
			original = imread("/home/ubuntu/testImage/12.png",0);
		if(h==12)
			original = imread("/home/ubuntu/testImage/13.png",0);
		if(h==13)
			original = imread("/home/ubuntu/testImage/14.png",0);
		if(h==14)
			original = imread("/home/ubuntu/testImage/15.png",0);
		if(h==15)
			original = imread("/home/ubuntu/testImage/16.png",0);
		if(h==16)
			original = imread("/home/ubuntu/testImage/17.png",0);
		if(h==17)
			original = imread("/home/ubuntu/testImage/18.png",0);
		if(h==18)
			original = imread("/home/ubuntu/testImage/19.png",0);
		if(h==19)
			original = imread("/home/ubuntu/testImage/20.png",0);
		/*strcpy(image,"/home/ubuntu/testImage/");
		sprintf()
		strcat(image,i+1);
		strcat(image,".png");
		cout<<"opening image..."<<endl;
		Mat original = imread(image,0);*/
		slice = original.cols/(clientsNumber+1);
		cout<<"Slices: "<<slice<<endl;
		cout<<"BRISK on image: "<<h+1<<endl;
		detector->detect(original,vectorOriginal);
		descriptorExtractor->compute(original,vectorOriginal,descriptor);
		for(int k = 0; k < OVERLAP; k++)
		{
			ovl = (original.cols*k)/100;
			cout<<"Overlap in pixel: "<<ovl<<endl;
			cols = 0;
			for(i=0;i<clientsNumber+1;i++)
			{
				if(i == clientsNumber)
				{
					cout<<"From: "<<cols<<" to: "<<cols+slice<<endl;
					splitImage[i] = original.colRange(cols,cols+slice);
				}
				else
				{
					cout<<"From: "<<cols<<" to: "<<cols+slice+ovl<<endl;
					splitImage[i] = original.colRange(cols,cols+slice+ovl);
				}
				cout<<"Detection on the distributed image..."<<endl;
				detector->detect(splitImage[i],vectorDistributed);
				descriptorExtractor->compute(splitImage[i],vectorDistributed,descriptorDistributed);
				for(int j = 0;j<vectorDistributed.size();j++)
				{
					vectorDistributed[j].pt.x = vectorDistributed[j].pt.x + i*slice;
					vectorOffloading.push_back(vectorDistributed[j]);
				}
				cout<<"Keypoints copied"<<endl;
				cols = cols + slice;
			}
			/*for(int i = 0;i<vectorOriginal.size();i++)
				fprintf(offloading,"%f %f %d\n",vectorOriginal[i].pt.x,vectorOriginal[i].pt.y,vectorOriginal[i].octave);
			fprintf(offloading,"distributed\n");
			for(int i = 0;i<vectorOffloading.size();i++)
				fprintf(offloading,"%f %f %d\n",vectorOffloading[i].pt.x,vectorOffloading[i].pt.y,vectorOffloading[i].octave);*/
			double distance[vectorOffloading.size()];
			double x,y,min;
			//Compute repeatability
			int counter = 0;
			float sameKp = 0, differentKp = 0;
			for(int i = 0;i<vectorOriginal.size();i++)
			{
				for(int m=0;m<vectorOffloading.size();m++,counter++)
				{
					x = pow(vectorOriginal[i].pt.x-vectorOffloading[m].pt.x,2);
					y = pow(vectorOriginal[i].pt.y-vectorOffloading[m].pt.y,2);
					distance[counter] = sqrt(x+y);
				}
				min = distance[0];
				for(int m=1;m<vectorOffloading.size();m++)
				{
					if(distance[m] < min)
						min = distance[m];
				}
				if(min > (1.5*(vectorOriginal[i].octave+1)))
					differentKp++;
				else
					sameKp++;
				counter = 0;
			}
			cout<<"same: "<<sameKp<<" different: "<<differentKp<<endl;
			float repeatability = (float)(sameKp/vectorOriginal.size())*100;
			printf("repeatability: %f\n",repeatability);
			fprintf(offloading,"%f ",repeatability);
		}
		fprintf(offloading,"\n");
	}
	fclose(offloading);
}
